// ...原有import不变
import {execSync} from "node:child_process";
import {doesAnyPatternMatch, post, split_message} from "./utils";
import {take_system_prompt} from "./prompt";

let useChinese = (process.env.INPUT_CHINESE || "true").toLowerCase() !== "false";
const language = !process.env.INPUT_CHINESE ? (process.env.INPUT_LANGUAGE || "Chinese") : (useChinese ? "Chinese" : "English");
const prompt_genre = (process.env.INPUT_PROMPT_GENRE || "");
const reviewers_prompt = (process.env.INPUT_REVIEWERS_PROMPT || "");
useChinese = language.toLowerCase() === "chinese";
const include_files = split_message(process.env.INPUT_INCLUDE_FILES || "");
const exclude_files = split_message(process.env.INPUT_EXCLUDE_FILES || "");
const review_pull_request = (process.env.INPUT_REVIEW_PULL_REQUEST || "").toLowerCase() === "true";

const system_prompt = reviewers_prompt || take_system_prompt(prompt_genre, language);
const model = process.env.INPUT_MODEL;
const host = process.env.INPUT_HOST;
const ai_token = process.env.INPUT_AI_TOKEN;
const ai_provider = (process.env.INPUT_AI_PROVIDER || "ollama").toLowerCase();

console.log("AI_PROVIDER:", ai_provider, "AI_TOKEN:", ai_token ? "✅" : "❌");

if (!host) {
  console.error('HOST input is required.');
  process.exit(1);
}
if (!model) {
  console.error('model input is required.');
  process.exit(1);
}

async function pushComments(message: string): Promise<any> {
  if (!process.env.INPUT_PULL_REQUEST_NUMBER) {
    console.log(message);
    return;
  }
  return await post({
    url: `${process.env.GITHUB_API_URL}/repos/${process.env.INPUT_REPOSITORY}/issues/${process.env.INPUT_PULL_REQUEST_NUMBER}/comments`,
    body: {body: message},
    header: {'Authorization': `token ${process.env.INPUT_TOKEN}`}
  })
}

async function aiGenerate({prompt, system}: any): Promise<any> {
  if (ai_provider === "openai") {
    return await aiGenerateOpenAI({prompt, system});
  } else {
    return await aiGenerateOllama({prompt, system});
  }
}

async function aiGenerateOllama({prompt, system}: any): Promise<any> {
  const data = JSON.stringify({
    prompt,
    model,
    stream: false,
    system: system || system_prompt,
    options: {
      tfs_z: 1.5,
      top_k: 30,
      top_p: 0.8,
      temperature: 0.7,
      num_ctx: 10240,
    }
  });
  return await post({
    url: `${host}/api/generate`,
    body: data,
    header: {'Authorization': ai_token ? `Bearer ${ai_token}` : ""}
  });
}

async function aiGenerateOpenAI({prompt, system}: any): Promise<any> {
  if (!ai_token || ai_token.trim() === "") {
    throw new Error("OpenAI API Key is required for openai provider");
  }

  const data = {
    model,
    messages: [
      {role: "system", content: system || system_prompt},
      {role: "user", content: prompt}
    ],
    temperature: 0.7
  };

  const res = await post({
    url: `${host}/v1/chat/completions`,
    body: data,
    header: {
      'Authorization': `Bearer ${ai_token}`,
      'Content-Type': 'application/json'
    }
  });

  console.log("🧪 OpenAI response:", JSON.stringify(res, null, 2)); // 👈 打印完整响应

  return res;
}



async function getPrDiffContext() {
  let items = [];
  const BASE_REF = process.env.INPUT_BASE_REF;
  try {
    execSync(`git fetch origin ${BASE_REF}`, {encoding: 'utf-8'});
    const diffOutput = execSync(`git diff --name-only origin/${BASE_REF}...HEAD`, {encoding: 'utf-8'});
    let files = diffOutput.trim().split("\n");
    for (let file of files) {
      if (!file) continue;
      if ((include_files.length > 0) && (!doesAnyPatternMatch(include_files, file))) continue;
      if ((exclude_files.length > 0) && (doesAnyPatternMatch(exclude_files, file))) continue;

      const fileDiffOutput = execSync(`git diff origin/${BASE_REF}...HEAD -- "${file}"`, {encoding: 'utf-8'});
      items.push({path: file, context: fileDiffOutput});
    }
  } catch (error) {
    console.error('Error executing git diff:', error);
  }
  return items;
}

async function getHeadDiffContext() {
  let items = [];
  try {
    const diffOutput = execSync(`git diff --name-only HEAD^`, {encoding: 'utf-8'});
    let files = diffOutput.trim().split("\n");
    for (let file of files) {
      if (!file) continue;
      if ((include_files.length > 0) && (!doesAnyPatternMatch(include_files, file))) continue;
      if ((exclude_files.length > 0) && (doesAnyPatternMatch(exclude_files, file))) continue;

      const fileDiffOutput = execSync(`git diff HEAD^ -- "${file}"`, {encoding: 'utf-8'});
      items.push({path: file, context: fileDiffOutput});
    }
  } catch (error) {
    console.error('Error executing git diff:', error);
  }
  return items;
}

async function aiCheckDiffContext() {
  try {
    let commit_sha_url = `${process.env.GITHUB_SERVER_URL}/${process.env.INPUT_REPOSITORY}/src/commit/${process.env.GITHUB_SHA}`;
    let items = review_pull_request ? await getPrDiffContext() : await getHeadDiffContext();
    for (let item of items) {
      try {
        let response = await aiGenerate({prompt: item.context, system: system_prompt});
        let commit = ai_provider === "openai" ? response.choices?.[0]?.message?.content : response.response;

        if (!commit) throw new Error("AI response is empty");

        if (commit.startsWith("```markdown")) {
          commit = commit.slice("```markdown".length).replace(/```$/, "");
        }

        let Review = useChinese ? "审核结果" : "Review";
        let comments = `# ${Review} \n${commit_sha_url}/${item.path} \n\n${commit}`;
        let resp = await pushComments(comments);
        if (!resp.id) throw new Error(useChinese ? "提交失败" : "Push comment failed");

        console.log(useChinese ? "提交成功：" : "Comment success: ", resp.id);
      } catch (e) {
        console.error("aiGenerate error:", e);
      }
    }
  } catch (error) {
    console.error('Error in review:', error);
    process.exit(1);
  }
}

aiCheckDiffContext()
  .then(() => console.log(useChinese ? "检查完成" : "Review finished"))
  .catch(e => {
    console.error(useChinese ? "检查失败:" : "Review error:", e);
    process.exit(1);
  });
